type BusType = {
  emit: (name: string, data: any) => void
  on: (name: string, callback: (data: any) => void) => void
}
class Bus implements BusType {
  private _event: { [key: number | string | symbol]: Array<Function> } = {}
  private static instance: Bus
  static getInstance() {
    if (!Bus.instance) {
      Bus.instance = new Bus()
    }
    return Bus.instance
  }
  emit(name: string, data: any) {
    if (this._event[name]) {
      this._event[name].forEach((callback) => {
        callback.apply(this, data)
      })
    }
  }
  on(name: string, callback: (data: any) => void) {
    if (!this._event[name]) {
      this._event[name] = []
    }
    this._event[name].push(callback)
  }
}

class eventBus {
  private static instance: eventBus
  private constructor() {}
  static getInstance() {
    if (!eventBus.instance) {
      eventBus.instance = new eventBus()
    }
    return eventBus.instance
  }
  private eventMap: Map<string, Array<(data: any) => void>> = new Map()
  public on(eventName: string, callback: (data: any) => void) {
    if (!this.eventMap.has(eventName)) {
      this.eventMap.set(eventName, [])
    }
    this.eventMap?.get(eventName)?.push(callback)
  }
  public emit(eventName: string, data: any) {
    if (this.eventMap.has(eventName)) {
      this.eventMap?.get(eventName)?.forEach((callback) => {
        callback(data)
      })
    }
  }
}
export default eventBus.getInstance()
export const bus = new Bus()
